package com.abu.edums.controller;


import com.abu.pojo.Course;
import com.abu.pojo.Subject;
import com.abu.pojo.Teacher;
import com.abu.vo.CategoryVO;
import com.abu.edums.service.SubjectService;
import com.abu.utils.Resp;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 课程科目 前端控制器
 * </p>
 *
 * @author 阿布
 * @since 2020-06-17
 */

@RestController
@RequestMapping("/eduservice/subject")
public class SubjectController {

    @Autowired
    private SubjectService subjectService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private static final String PREFIX = "CATEGORYVO:PREFIX:";

    @PostMapping("upload")
    public Resp getFile(MultipartFile file) {
        this.subjectService.getFile(file);
        return Resp.ok();
    }

    /**
     * 查询频繁通过加缓存解决
     *
     * @param id
     * @return
     */
    @GetMapping("getAllSubject/{id}")
    public Resp getAllSubject(@PathVariable("id") String id) {

//        1. 先查询缓存有没有
        String categoryVosJson = this.redisTemplate.opsForValue().get(PREFIX);
//        2.有的话直接返回
        if (StringUtils.isNotBlank(categoryVosJson)) {
            List<CategoryVO> categoryVOS = JSON.parseArray(categoryVosJson, CategoryVO.class);
            return Resp.ok().data("list", categoryVOS);
        }
//        3.没有的话加分布式锁(解决缓存击穿)
        RLock lock = this.redissonClient.getLock("lock");
        lock.lock();
//        4.再次查询缓存
        String categoryVosJson2 = this.redisTemplate.opsForValue().get(PREFIX);
        if (StringUtils.isNotBlank(categoryVosJson2)) {
            List<CategoryVO> categoryVOList = JSON.parseArray(categoryVosJson2, CategoryVO.class);
//        5.有的话直接返回
            lock.unlock();
            return Resp.ok().data("list", categoryVOList);
        }
//        6.没有的话查询数据库
        List<CategoryVO> categoryVos = this.subjectService.queryAllByPid(id);

//        7.将结果集放入缓存中（将查询出的不存在的数据也放入缓存中，解决了缓存穿透。将缓存过期时间设置成了随机值，防止缓存雪崩）
        this.redisTemplate.opsForValue().set(PREFIX, JSON.toJSONString(categoryVos), 60 * new Random().nextInt(50) + 1, TimeUnit.SECONDS);
//        释放锁
        lock.unlock();
        return Resp.ok().data("list", categoryVos);
    }

}

